﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace RG.Common.WPF.Controls.DateTimePicker
{
    [SupportDataBinding]
    public partial class UFDameer : INotifyPropertyChanged, IFirePropertyChanged 
    {
        private DateTime selectedDate;
        public DateTime SelectedDate
        {
            get { return selectedDate; }
            set { selectedDate = value; RefreshResalt(); }
        }

        private int selectedHour;
        public int SelectedHour
        {
            get { return selectedHour; }
            set { selectedHour = value; RefreshResalt(); }
        }

        private int selectedMin;
        public int SelectedMin
        {
            get { return selectedMin; }
            set { selectedMin = value; RefreshResalt(); }
        }

        public List<int> Hours { get; set; }
        public List<int> Minuts { get; set; }

        public UFDameer()
        {
            InitializeComponent();
            Hours = new List<int>();
            for (int i = 0; i < 24; i++)
                Hours.Add(i);
            Minuts = new List<int>();
            for (int i = 0; i < 60; i = i + 10)
                Minuts.Add(i);
            SetValue(ValueProperty, DateTime.Now);
            SetValue(HTypeProperty, HourType.FullDay);
            SetValue(MTypeProperty, MinutType.FullHour);
            DataContext = this;
        }

        #region Value

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof (DateTime?), typeof (UFDameer),
                                        new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.
                                                                                        BindsTwoWayByDefault,
                                                                      OnValueChanged,
                                                                      CoerceDValue, true,
                                                                      UpdateSourceTrigger.PropertyChanged));

        public DateTime? Value
        {
            set { SetValue(ValueProperty, value); }
            get
            {
                RefreshResalt();
                return (DateTime?)GetValue(ValueProperty);
            }
        }

        private static object CoerceDValue(DependencyObject d, object basevalue)
        {
            var dameer = (UFDameer)d;
            return new DateTime(dameer.SelectedDate.Year, dameer.SelectedDate.Month, dameer.SelectedDate.Day, Convert.ToInt32(dameer.SelectedHour), Convert.ToInt32(dameer.SelectedMin), 0);
        }

        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dameer = (UFDameer) d;
            if (!dameer.Value.HasValue || dameer.Value.Value < new DateTime(2000, 1, 1))
                dameer.Value = DateTime.Now;
            dameer.RefreshDate();
        }

        #endregion

        #region HourType

        public static readonly DependencyProperty HTypeProperty =
            DependencyProperty.Register("HType", typeof(HourType), typeof(UFDameer),
                                        new PropertyMetadata(DoHList));

        private static void DoHList(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dameer = (UFDameer)d;
            var hrs = new List<int>();
            switch ((HourType)e.NewValue)
            {
                case HourType.FullDay:
                    for (int i = 0; i < 24; i++)
                        hrs.Add(i);
                    break;
                case HourType.WorkDay:
                    for (int i = 8; i < 20; i++)
                        hrs.Add(i);
                    break;
                default:
                    for (int i = 0; i < 24; i++)
                        hrs.Add(i);
                    break;
            }
            dameer.Hours = new List<int>(hrs);
        }

        public HourType HType
        {
            set { SetValue(HTypeProperty, value); }
            get { return (HourType)GetValue(HTypeProperty); }
        }

        #endregion

        #region MinitType

        public static readonly DependencyProperty MTypeProperty =
            DependencyProperty.Register("MType", typeof(MinutType), typeof(UFDameer),
                                        new PropertyMetadata(DoMList));

        public MinutType MType
        {
            set { SetValue(MTypeProperty, value); }
            get { return (MinutType)GetValue(MTypeProperty); }
        }

        private static void DoMList(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dameer = (UFDameer)d;
            var mins = new List<int>();
            switch ((MinutType)e.NewValue)
            {
                case MinutType.FullHour:
                    for (int i = 0; i < 60; i = i + 10)
                        mins.Add(i);
                    break;
                case MinutType.HalfHour:
                    mins.Add(0);
                    mins.Add(30);
                    break;
                default:
                    for (int i = 0; i < 60; i = i + 10)
                        mins.Add(i);
                    break;
            }
            dameer.Minuts = new List<int>(mins);
        }
        #endregion

        private void RefreshDate()
        {
            if (!Value.HasValue || Value.Value < new DateTime(2000, 1, 1))
                Value = DateTime.Now;
            selectedDate = Value.Value.Date;
            selectedHour = Value.Value.Hour;
            selectedMin = MinutToString(Value.Value.Minute);
            
            OnPropertyChanged("SelectedDate");
            OnPropertyChanged("SelectedHour");
            OnPropertyChanged("SelectedMin");
        }

        private int MinutToString(int min)
        {
            if (min == 0) return 0;
            switch (MType)
            {
                case MinutType.FullHour:
                    var ret = decimal.Round(((decimal) min)/10)*10;
                    return (int) ret;
                case MinutType.HalfHour:
                    if (min > 15 && min < 45) return 30;
                    return 0;
                default : return 0;
            }
        }

        private void RefreshResalt()
        {
            //if(string.IsNullOrEmpty(SelectedHour) || string.IsNullOrEmpty(SelectedMin)) return;
            var val = new DateTime(SelectedDate.Year, SelectedDate.Month, SelectedDate.Day, SelectedHour, SelectedMin, 0); 
            SetValue(ValueProperty, val);
        }


        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Implementation of IFirePropertyChanged

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

    public enum HourType {FullDay, WorkDay}
    public enum MinutType {FullHour, HalfHour}
}
